home *** CD-ROM | disk | FTP | other *** search
/ Aminet 39 / Aminet 39 (2000)(Schatztruhe)[!][Oct 2000].iso / Aminet / gfx / misc / Splitmpeg.lha / Splitmpeg / src / parsers.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-07-22  |  6.9 KB  |  275 lines

  1.  
  2. /*
  3.  * Copyright (c) 1994 Michael Simmons.
  4.  * All rights reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose, without fee, and without written agreement is
  8.  * hereby granted, provided that the above copyright notice and the following
  9.  * two paragraphs appear in all copies of this software.
  10.  *
  11.  * IN NO EVENT SHALL MICHAEL SIMMONS BE LIABLE TO ANY PARTY FOR
  12.  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
  13.  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF MICHAEL SIMMONS
  14.  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  15.  *
  16.  * THE MICHAEL SIMMONS SPECIFICALLY DISCLAIMS ANY WARRANTIES,
  17.  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  18.  * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
  19.  * ON AN "AS IS" BASIS, AND MICHAEL SIMMONS HAS NO OBLIGATION TO
  20.  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  21.  *
  22.  * I can be contacted via
  23.  * Email: michael@ecel.uwa.edu.au
  24.  * Post: P.O. Box 506, NEDLANDS WA 6009, AUSTRALIA
  25.  *
  26.  * Amigaversion by Tobias Seiler in 1997
  27.  * Email: tabs@blader.com
  28.  */
  29.  
  30. /*
  31.  * Routines to parse the different parts of a pack
  32.  */
  33.  
  34. #include    "main.h"
  35.  
  36. #define check_marker                      \
  37. {                                         \
  38.   get_bits1(&data);                       \
  39.   if ( data != 1)                         \
  40.   return (err | ERR_INVALID_MARKER);      \
  41. }
  42.  
  43. /*
  44.  * Parses the pack header
  45.  *
  46.  */
  47.  
  48. int parse_pack_header(Pack_Header *pack_header)
  49. {
  50.   unsigned int data;
  51.   int err = ERR_PARSE_PACK_HDR;
  52.  
  53.   flush_bits(32); /* Flush PACK_START_CODE */
  54.  
  55.   get_bits4(&data);
  56.   if( data != 2)
  57.   return (err | ERR_INVALID_BITS);
  58.  
  59.   /* Get System Clock Reference*/
  60.   get_bits1(&data);
  61.   pack_header->SCR_hibit = data;
  62.   get_bits2(&data);
  63.   pack_header->SCR = data << 30;
  64.   check_marker;
  65.   get_bits15(&data);
  66.   pack_header->SCR |= data << 15;
  67.   check_marker;
  68.   get_bits15(&data);
  69.   pack_header->SCR |= data;
  70.   check_marker;
  71.   check_marker;
  72.  
  73.   /* Get Mux Rate */
  74.   get_bits22(&data);
  75.   pack_header->mux_rate = data;
  76.   check_marker;
  77.  
  78.   return NO_ERROR;
  79. }
  80.  
  81. /*
  82.  * Parses the system header
  83.  */
  84.  
  85. int parse_system_header( System_Header *system_header)
  86. {
  87.   unsigned int data;
  88.   unsigned int stream_id;
  89.   int err = ERR_PARSE_SYSTEM_HDR;
  90.  
  91.   flush_bits(32); /* flush SYSTEM_HEADER_START_CODE */
  92.  
  93.   /* extract system header information */
  94.   get_bits16(&data);
  95.   system_header->header_length = data;
  96.   check_marker;
  97.   get_bits22(&data);
  98.   system_header->rate_bound = data;
  99.   check_marker;
  100.   get_bits6(&data);
  101.   system_header->audio_bound = data;
  102.   get_bits1(&data);
  103.   system_header->fixed_flag = data;
  104.   get_bits1(&data);
  105.   system_header->CSPS_flag = data;
  106.   get_bits1(&data);
  107.   system_header->audio_lock_flag = data;
  108.   get_bits1(&data);
  109.   system_header->video_lock_flag = data;
  110.   check_marker;
  111.   get_bits5(&data);
  112.   system_header->video_bound = data;
  113.   get_bits8(&data);
  114.   system_header->reserved_byte = data;
  115.  
  116.   /* flag STD buffer bounds for each stream as invalid*/
  117.   for( stream_id=0; stream_id< MAX_NUM_STREAMS; stream_id++)
  118.   system_header->STD_flag[stream_id] = FALSE;
  119.  
  120.   while ( next_bits(1,1)){
  121.  
  122.     /* get stream number */
  123.     get_bits8(&data);
  124.     if( data < (RESERVED_STREAM & 0xff) || data > (RESERVED_DATA_STREAM_15 & 0xff))
  125.     return (err | ERR_INVALID_STREAM_NUM );
  126.     stream_id = data - (RESERVED_STREAM & 0xff);
  127.  
  128.     get_bits2(&data);
  129.     if( data != 3 )
  130.     return (err | ERR_INVALID_BITS);
  131.  
  132.     /* Extract the STD buffer bounds for stream stream_id and flag it as valid */
  133.     get_bits1(&data);
  134.     system_header->STD_scale_bound[stream_id] = data;
  135.     get_bits13(&data);
  136.     system_header->STD_size_bound[stream_id] = data;
  137.     system_header->STD_flag[stream_id] = TRUE;
  138.   }
  139.  
  140.   return NO_ERROR;
  141. }
  142.  
  143. /*
  144.  * Reads in a packet from the stream
  145.  * Updates the current stream info
  146.  * Create a buffer and put the packet data in it
  147. */
  148.  
  149. int parse_packet(Packet *packet)
  150. {
  151.   unsigned int    data = 0;
  152.   unsigned int    byte_count;
  153.   int err = ERR_PARSE_SYSTEM_HDR;
  154.   int    i,stream_num;
  155.   char   *bptr;
  156.   get_bits24(&data);
  157.   get_bits8(&data);
  158.  
  159.   if( data < (RESERVED_STREAM & 0xff) || data > (RESERVED_DATA_STREAM_15 & 0xff))
  160.   return (err | ERR_INVALID_STREAM_NUM );
  161.  
  162.   packet->stream_id = data;
  163.  
  164.   stream_num = packet->stream_id - (RESERVED_STREAM & 0xff);
  165.  
  166.   get_bits16(&data);
  167.   packet->packet_length = data;
  168.  
  169.   byte_count =0;
  170.  
  171.   packet->STD_flag=packet->PTS_Flag=packet->DTS_Flag = FALSE;
  172.  
  173.   if( packet->stream_id != PRIVATE_STREAM_2 ){
  174.  
  175.     /* flush stuffing bytes */
  176.     while( next_bits(8,0xff)){
  177.       flush_bits(8);
  178.       byte_count++;
  179.     }
  180.  
  181.     if( next_bits(2,1)){
  182.       flush_bits(2);
  183.  
  184.       /* Get STD buffer size and flag it as present in packet*/
  185.       get_bits1(&data);
  186.       streamInfo[stream_num].STD_scale=data;
  187.       get_bits13(&data);
  188.       streamInfo[stream_num].STD_size=data;
  189.       packet->STD_flag=TRUE;
  190.       byte_count +=2;
  191.     }
  192.  
  193.     if( next_bits(4,2)){
  194.       flush_bits(4);
  195.  
  196.       /* Get presentation time stamp and flag it as present in packet*/
  197.       get_bits1(&data);
  198.       streamInfo[stream_num].PTS_hibit = data;
  199.       get_bits2(&data);
  200.       streamInfo[stream_num].PTS = data << 30;
  201.       check_marker;
  202.       get_bits15(&data);
  203.       streamInfo[stream_num].PTS |= data << 15;
  204.       check_marker;
  205.       get_bits15(&data);
  206.       streamInfo[stream_num].PTS |= data;
  207.       check_marker;
  208.       packet->PTS_Flag=TRUE;
  209.       byte_count +=5;
  210.  
  211.     }
  212.     else if (next_bits(4,3)){
  213.       flush_bits(4);
  214.  
  215.       /* Get presentation time stamp and decoding time stamp */
  216.       /* and flag them as present in packet*/
  217.       get_bits1(&data);
  218.       streamInfo[stream_num].PTS_hibit = data;
  219.       get_bits2(&data);
  220.       streamInfo[stream_num].PTS = data << 30;
  221.       check_marker;
  222.       get_bits15(&data);
  223.       streamInfo[stream_num].PTS |= data << 15;
  224.       check_marker;
  225.       get_bits15(&data);
  226.       streamInfo[stream_num].PTS |= data;
  227.       check_marker;
  228.       packet->PTS_Flag=TRUE;
  229.  
  230.       if( !next_bits(4,1) )
  231.       return (err | ERR_INVALID_BITS);
  232.       flush_bits(4);
  233.  
  234.       get_bits1(&data);
  235.       streamInfo[stream_num].DTS_hibit = data;
  236.       get_bits2(&data);
  237.       streamInfo[stream_num].DTS = data << 30;
  238.       check_marker;
  239.       get_bits15(&data);
  240.       streamInfo[stream_num].DTS |= data << 15;
  241.       check_marker;
  242.       get_bits15(&data);
  243.       streamInfo[stream_num].DTS |= data;
  244.       check_marker;
  245.       packet->DTS_Flag=TRUE;
  246.       byte_count +=10;
  247.  
  248.     }
  249.     else{
  250.       if( !next_bits(8,0x0f))
  251.       return (err | ERR_INVALID_BITS);
  252.       flush_bits(8);
  253.       byte_count++;
  254.     }
  255.   }
  256.  
  257.   /* create a buffer to contain the packet data and copy it in */
  258.   packet->buffer_size = packet->packet_length - byte_count;
  259.  
  260.   packet->buffer = (char *) malloc(packet->buffer_size);
  261.   if(packet->buffer == NULL){
  262.     return (err | ERR_MALLOC);
  263.   }
  264.  
  265.   bptr = packet->buffer;
  266.  
  267.   for( i=0; i < (packet->buffer_size); i++){
  268.     get_bits8(&data);
  269.     *bptr++=(char) data;
  270.   }
  271.  
  272.   return NO_ERROR;
  273. }
  274.  
  275.